/*
 * Copyright (C) 2010 ZXing authors
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.zxing.result.supplement;

import android.content.Context;
import android.os.AsyncTask;
import android.text.Spannable;
import android.text.SpannableString;
import android.text.Spanned;
import android.text.method.LinkMovementMethod;
import android.text.style.URLSpan;
import android.util.Log;
import android.widget.TextView;

import java.io.IOException;
import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.Collection;

import com.daxiong.zxing.client.result.ISBNParsedResult;
import com.daxiong.zxing.client.result.ParsedResult;
import com.daxiong.zxing.client.result.ProductParsedResult;
import com.daxiong.zxing.client.result.URIParsedResult;

public abstract class SupplementalInfoRetriever extends AsyncTask<Object, Object, Object> {

	private static final String TAG = "SupplementalInfo";

	public static void maybeInvokeRetrieval(TextView textView, ParsedResult result, Context context) {
		if (result instanceof URIParsedResult) {
			SupplementalInfoRetriever uriRetriever = new URIResultInfoRetriever(textView, (URIParsedResult) result,
					context);
			uriRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
			SupplementalInfoRetriever titleRetriever = new TitleRetriever(textView, (URIParsedResult) result);
			titleRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
		} else if (result instanceof ProductParsedResult) {
			ProductParsedResult productParsedResult = (ProductParsedResult) result;
			String productID = productParsedResult.getProductID();
			SupplementalInfoRetriever productRetriever = new ProductResultInfoRetriever(textView, productID,
					 context);
			productRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
		} else if (result instanceof ISBNParsedResult) {
			String isbn = ((ISBNParsedResult) result).getISBN();
			SupplementalInfoRetriever productInfoRetriever = new ProductResultInfoRetriever(textView, isbn,
					context);
			productInfoRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
			SupplementalInfoRetriever bookInfoRetriever = new BookResultInfoRetriever(textView, isbn,
					context);
			bookInfoRetriever.executeOnExecutor(AsyncTask.THREAD_POOL_EXECUTOR);
		}
	}

	private final WeakReference<TextView> textViewRef;
	private final Collection<Spannable> newContents;
	private final Collection<String[]> newHistories;

	SupplementalInfoRetriever(TextView textView) {
		textViewRef = new WeakReference<>(textView);
		newContents = new ArrayList<>();
		newHistories = new ArrayList<>();
	}

	@Override
	public final Object doInBackground(Object... args) {
		try {
			retrieveSupplementalInfo();
		} catch (IOException e) {
			Log.w(TAG, e);
		}
		return null;
	}

	@Override
	protected final void onPostExecute(Object arg) {
		TextView textView = textViewRef.get();
		if (textView != null) {
			for (CharSequence content : newContents) {
				textView.append(content);
			}
			textView.setMovementMethod(LinkMovementMethod.getInstance());
		}
//		if (historyManager != null) {
//			for (String[] text : newHistories) {
//				historyManager.addHistoryItemDetails(text[0], text[1]);
//			}
//		}
	}

	abstract void retrieveSupplementalInfo() throws IOException;

	final void append(String itemID, String source, String[] newTexts, String linkURL) {

		StringBuilder newTextCombined = new StringBuilder();

		if (source != null) {
			newTextCombined.append(source).append(' ');
		}

		int linkStart = newTextCombined.length();

		boolean first = true;
		for (String newText : newTexts) {
			if (first) {
				newTextCombined.append(newText);
				first = false;
			} else {
				newTextCombined.append(" [");
				newTextCombined.append(newText);
				newTextCombined.append(']');
			}
		}

		int linkEnd = newTextCombined.length();

		String newText = newTextCombined.toString();
		Spannable content = new SpannableString(newText + "\n\n");
		if (linkURL != null) {
			// Strangely, some Android browsers don't seem to register to handle
			// HTTP:// or HTTPS://.
			// Lower-case these as it should always be OK to lower-case these
			// schemes.
			if (linkURL.startsWith("HTTP://")) {
				linkURL = "http" + linkURL.substring(4);
			} else if (linkURL.startsWith("HTTPS://")) {
				linkURL = "https" + linkURL.substring(5);
			}
			content.setSpan(new URLSpan(linkURL), linkStart, linkEnd, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE);
		}

		newContents.add(content);
		newHistories.add(new String[] { itemID, newText });
	}

	static void maybeAddText(String text, Collection<String> texts) {
		if (text != null && !text.isEmpty()) {
			texts.add(text);
		}
	}

	static void maybeAddTextSeries(Collection<String> textSeries, Collection<String> texts) {
		if (textSeries != null && !textSeries.isEmpty()) {
			boolean first = true;
			StringBuilder authorsText = new StringBuilder();
			for (String author : textSeries) {
				if (first) {
					first = false;
				} else {
					authorsText.append(", ");
				}
				authorsText.append(author);
			}
			texts.add(authorsText.toString());
		}
	}

}
